﻿using SS.WPF.Framework.ViewModel.Navigation;

namespace SS.WPF.Framework.ViewModel.Screen
{
    using System.ComponentModel;

    public class EditorViewModelBase : ViewModelBase, IEditor, IEditable
    {
        private bool _isEditorDirty;

        public object Input
        {
            get;
            set;
        }

        public virtual bool IsEditorDirty
        {
            get { return this._isEditorDirty; }
            set
            {
                this._isEditorDirty = value;

                var input = this.Input;
                while (input is IEditable)
                {
                    var editable = (IEditable) input;

                    editable.IsEditorDirty = this.IsEditorDirty;

                    input = input as INavigationNode;
                    if (input != null)
                    {
                        input = ((INavigationNode) input).Parent;
                    }
                }


                this.NotifyOfPropertyChange(() => this.IsEditorDirty);
                this.NotifyOfPropertyChange(() => this.EditingStatus);
            }
        }

        public virtual bool IsEnable
        {
            get
            {
                var editable = this.Input as IEditable;
                if (editable != null && editable.EditingStatus == EditingStatus.Deleted)
                {
                    return false;
                }

                return true;
            }
        }

        protected override void OnInitialize()
        {
            var nofitychanged = this.Input as INotifyPropertyChanged;
            if (nofitychanged != null)
            {
                nofitychanged.PropertyChanged += this.OnPropertyChanged;
            }

            base.OnInitialize();
        }

        protected virtual void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "EditingStatus")
            {
                this.NotifyOfPropertyChange(() => this.IsEnable);
            }
        }

        #region Implementation of IEditable

        //private EditingStatus _editingStatus;



        public virtual EditingStatus EditingStatus
        {
            get
            {
                //if (this.IsDeleted)
                //{
                //    return EditingStatus.Deleted;
                //}

                //if (this.HasError)
                //{
                //    return EditingStatus.Error;
                //}

                //if (this.IsAdded)
                //{
                //    return EditingStatus.Added;
                //}

                return this.IsEditorDirty ? EditingStatus.Modified : EditingStatus.None;

                //return this._editingStatus;
            }
            //set
            //{
            //    this._editingStatus = value;
            //    this.NotifyOfPropertyChange(() => this.EditingStatus);
            //}
        }

        private bool _hasError;

        public bool HasError
        {
            get
            {
                return this._hasError;
            }
            set
            {
                this._hasError = value;
                var node = this.Input as INavigationNode;
                if (node != null)
                {
                    node.HasError = this.HasError;
                }

                this.NotifyOfPropertyChange(() => this.HasError);
                this.NotifyOfPropertyChange(() => this.EditingStatus);
            }
        }

        #endregion

        public virtual void ResetDirty()
        {

        }

        public virtual void RevertData()
        {
            //this.Errors.Clear();
            // this.PreEditingStatus = EditingStatus.None;
        }

        public virtual bool IsIdChanged
        {
            get { return false; }
        }

        public virtual bool IsGeneralSettingDirty
        {
            get { return false; }
        }

        public virtual bool IsMetadataOrDictionaryPathChanged
        {
            get { return false; }
        }
    }

    public class EditorViewModelBase<TInput> : EditorViewModelBase, IEditor<TInput>
        where TInput : IEditable
    {
        public new TInput Input
        {
            get
            {
                return (TInput)(base.Input);
            }
            set
            {
                base.Input = value;
                this.NotifyOfPropertyChange(() => this.Input);
            }
        }

        public override void RevertData()
        {
            base.RevertData();
            //this.Input.EditingStatus = EditingStatus.None;
            this.Input.HasError = this.HasError;
            this.Input.IsEditorDirty = this.IsEditorDirty;
            var node = this.Input as NavigationNode;

            if (node != null)
            {
                //node.PreEditingStatus = EditingStatus.None;
                node.IsEditorDirty = false;
            }
        }
    }
}
